home *** CD-ROM | disk | FTP | other *** search
- // Track.java
-
- /*
- * Copyright (c) 1996 by Corey Trager.
- *
- * Permission to use, copy, and distribute this software for
- * any purpose and without fee is hereby granted provided
- * that this copyright notice appears in all copies.
- *
- */
-
- // Track is the abstract class
- // StraightTrack, CurvedTrack, and SwitchTrack are
- // all derived from Track.
-
- // The Track class and the TrackCollection class
- // collaborate
-
-
- import java.lang.Math;
- // import java.awt.*;
- import java.awt.Graphics;
- import java.awt.Color;
-
- abstract class Track {
-
- // Increment each time a track is constructed
- private protected static int nextId = 0;
-
- // We need to talk to our container sometimes
- static TrackCollection tc;
-
- // Constants
- static final int EMPTY = 999;
- static final double SNAP_DIST = 6.0;
- static final int NOT_GRIPPED = 0;
- static final int TRANSLATE_MODE = 1;
- static final int ROTATE_MODE_XY = 2;
- static final int ROTATE_MODE_PQ = 3;
- static final int GRIP_RANGE = 9;
- static final int TIE_SIZE = 3;
-
- int id; // id happens to == index in lines array
-
- // state
- int transformMode = NOT_GRIPPED;
- boolean isGripped = false;
-
- // Ties
- Line ties[];
- int tieCnt;
- int connections[];
- DblPoint connectionPoints[];
- int connectionCnt;
-
- private protected double x, y, ox, oy;
- double cx, cy;
-
- abstract void move(int argX, int argY);
- abstract void rotate(double theta);
-
- Track () {
- id = nextId++;
- }
-
- void draw (Graphics g) {
-
- int i;
-
- for (i = 0; i < tieCnt; i++)
- ties[i].draw(g);
-
- for (i = 0; i < connectionCnt; i++) {
- if (connections[i] != EMPTY)
- g.setColor (Color.green);
- else
- g.setColor (Color.red);
- g.drawOval (
- (int)connectionPoints[i].x - 3,
- (int)connectionPoints[i].y - 3,
- 6, 6);
- }
- }
-
- boolean isConnectedTo (int id) {
-
- for (int i = 0; i < connectionCnt; i++) {
- if (connections[i] == id)
- return true;
- }
-
- return false;
- }
-
- // Get track connected to this track which is
- // NOT the same as the incoming track
- int getNext (int id) {
- for (int i = 0; i < connectionCnt; i++) {
- if (connections[i] != EMPTY
- && connections[i] != id)
- return connections[i];
- }
-
- return -1;
- }
-
- void instantiateObjects() {
- ties = new Line[tieCnt];
- connections = new int[connectionCnt];
- connectionPoints = new DblPoint[connectionCnt];
-
- for (int i = 0; i < tieCnt; i++)
- ties[i] = new Line(new DblPoint(0,0),new DblPoint(0,0));
-
- for (int i = 0; i < connectionCnt; i++) {
- connections[i] = EMPTY;
- connectionPoints[i] = new DblPoint (0, 0);
- }
- }
-
-
- abstract void setMainLines();
- abstract void setTies();
- abstract void setConnectionPoints();
-
- void restore () {
-
- for (int i = 0; i < connectionCnt; i++)
- connections[i] = Track.EMPTY;
-
- }
-
- int appendRunPoints (DblPoint pts[], int index, int id) {
- if (connections[0] == id) {
- for (int i = 0; i < tieCnt; i++) {
- pts[index] = new DblPoint (ties[i].c);
- index++;
- }
- pts[index] = new DblPoint (connectionPoints[1]);
- index++;
- }
- else {
- for (int i = tieCnt - 1; i > -1; i--) {
- pts[index] = new DblPoint (
- ties[i].c.x,
- ties[i].c.y);
- index++;
- }
- pts[index] = new DblPoint (connectionPoints[0]);
- index++;
- }
- return index;
- }
-
- void rotate(int x, int y) {
-
- DblPoint pivot;
- DblPoint grip;
- DblPoint mouse = new DblPoint ((double) x, ((double) y));
-
- if (transformMode == ROTATE_MODE_XY) {
- pivot = new DblPoint (connectionPoints[0]);
- grip = new DblPoint (connectionPoints[1]);
- }
- else {
- pivot = new DblPoint (connectionPoints[1]);
- grip = new DblPoint (connectionPoints[0]);
- }
-
- // The y grows larger when moving down but I can't
- // think that way. Make y increase as I move the
- // mouse up
-
- double thetaMouse = - (pivot.angleToPoint (mouse));
- double thetaGrip = - (pivot.angleToPoint (grip));
-
- if (thetaMouse >= thetaGrip) {
- double thetaCCW = thetaMouse - thetaGrip; // counter-clockwise
- if (thetaCCW <= Geometry.ONE_EIGHTY_DEGREES)
- rotate (thetaCCW);
- else
- rotate (-1.0 * (Geometry.THREE_SIXTY_DEGREES - thetaCCW));
- }
- else {
- double thetaCW = thetaMouse - thetaGrip;
- if (thetaCW < -Geometry.ONE_EIGHTY_DEGREES)
- rotate (thetaCW);
- else
- rotate (Geometry.THREE_SIXTY_DEGREES + thetaCW);
- }
- }
-
-
-
- void releaseGrip () {
- transformMode = NOT_GRIPPED;
- }
-
- void detach () {
-
- for (int i = 0; i < connectionCnt; i++) {
- if (connections[i] != EMPTY) {
- tc.getTrack(connections[i]).detach(id);
- connections[i] = EMPTY;
- }
- }
-
- }
-
- void detach (int otherId) {
-
- // Only detach end which
- // is connected to incoming guy
- for (int i = 0; i < connectionCnt; i++) {
- if (connections[i] == otherId)
- connections[i] = EMPTY;
- }
-
- }
-
- int tryToGrip (int x, int y, double distArg ) {
- double distC;
- double distXY;
- double distPQ;
- DblPoint xy = connectionPoints[0];
- DblPoint pq = connectionPoints[1];
- distC = Math.sqrt ((this.cx - (double) x) * (this.cx - (double) x)
- + (this.cy - y) * (this.cy - (double) y));
- distXY = Math.sqrt ((xy.x - (double) x) * (xy.x - (double) x)
- + (xy.y - y) * (xy.y - (double) y));
- distPQ = Math.sqrt ((pq.x - (double) x) * (pq.x - (double) x)
- + (pq.y - y) * (pq.y - (double) y));
-
- // check if gripped in the middle
- if (distC < GRIP_RANGE
- || distXY < GRIP_RANGE
- || distPQ < GRIP_RANGE) {
- if (distC <= distXY && distC <= distPQ) {
- transformMode = TRANSLATE_MODE;
- distArg = distC;
- }
- else
- if (distXY <= distC && distXY <= distPQ) {
- transformMode = ROTATE_MODE_PQ;
- distArg = distXY;
- }
- else {
- transformMode = ROTATE_MODE_XY;
- distArg = distPQ;
- }
- }
- else {
- transformMode = NOT_GRIPPED;
- }
-
- return transformMode;
- }
-
- void prepareForCircuitInquiry () {}
- }
- //////////////////////////////////////////////////////
- //////////////////////////////////////////////////////
- // StraightTrack
- //////////////////////////////////////////////////////
- //////////////////////////////////////////////////////
- class StraightTrack extends Track {
-
- // Main line
- Line ln;
-
- StraightTrack (int x, int y) {
-
- tieCnt = 3;
- connectionCnt = 2;
-
- instantiateObjects();
-
- // save original position
- ox = (double) x;
- oy = (double) y;
-
- restore ();
- }
-
- void setMainLines () {
- ln = new Line(
- new DblPoint(x, y),
- new DblPoint(x + 40.0, y));
- }
-
- void setTies () {
-
- double up = ln.c.y + TIE_SIZE;
- double down = ln.c.y - TIE_SIZE;
- double inc = 10.0;
- ties[0].v1.x = x + inc;
- ties[0].v1.y = up;
- ties[0].v2.x = x + inc;
- ties[0].v2.y = down;
- ties[1].v1.x = ln.c.x;
- ties[1].v1.y = up;
- ties[1].v2.x = ln.c.x;
- ties[1].v2.y = down;
- ties[2].v1.x = x + (3 * inc);
- ties[2].v1.y = up;
- ties[2].v2.x = x + (3 * inc);
- ties[2].v2.y = down;
- }
-
- void setConnectionPoints () {
- connectionPoints[0].x = ln.v1.x;
- connectionPoints[0].y = ln.v1.y;
- connectionPoints[1].x = ln.v2.x;
- connectionPoints[1].y = ln.v2.y;
- cx = ln.c.x;
- cy = ln.c.y;
- }
-
- void restore() {
- x = ox;
- y = oy;
- super.restore();
- setMainLines();
- setTies();
- setConnectionPoints();
- }
-
- void move(int argX, int argY) {
-
- DblPoint vector = ln.moveTo (
- (double) argX, (double) argY);
-
- for (int i = 0; i < tieCnt; i++)
- ties[i].translate(vector);
-
- setConnectionPoints();
- }
-
- void rotate(double theta) {
-
- DblPoint vector;
-
- if (transformMode == ROTATE_MODE_XY)
- vector = DblPoint.vector (Geometry.ORIGIN, ln.v1);
- else if (transformMode == ROTATE_MODE_PQ)
- vector = DblPoint.vector (Geometry.ORIGIN, ln.v2);
- else
- vector = DblPoint.vector (Geometry.ORIGIN, ln.c);
-
- ln.rotate(vector, theta);
- for (int i = 0; i < tieCnt; i++)
- ties[i].rotate (vector, theta);
-
- setConnectionPoints();
-
- }
-
- void draw (Graphics g) {
-
- if (transformMode == NOT_GRIPPED)
- g.setColor(Color.black);
- else
- g.setColor(Color.blue);
-
- ln.draw (g);
- super.draw(g);
- }
-
-
-
-
- } // end class StraightTrack
-
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
- // CurvedTrack
- ///////////////////////////////////////////////
- ///////////////////////////////////////////////
-
- // You must construct a piece of track as the upper
- // right quadrant of a circle. After you construct
- // it you can move it whereever you want
-
- class CurvedTrack extends Track {
-
- // Main line
- Arc arc;
-
- CurvedTrack (int x, int y)
- {
- tieCnt = 5;
- connectionCnt = 2;
-
- instantiateObjects();
-
- ox = (double) x;
- oy = (double) y;
-
- restore ();
- }
-
-
- void setMainLines () {
- arc = new Arc(new DblPoint(x,y+40), 40, 0.0, Geometry.NINETY_DEGREES);
- }
-
- void setTies () {
-
- double centerX = arc.c.x;
- double centerY = arc.c.y;
-
- double theta;
- DblPoint vector = DblPoint.vector (Geometry.ORIGIN, arc.c);
- DblPoint pt = new DblPoint (0,0);
-
- for (int i = 0; i < tieCnt; i++) {
- ties[i].v1.x = centerX;
- ties[i].v1.y = centerY + 3;
- ties[i].v2.x = centerX;
- ties[i].v2.y = centerY - 3;
- theta = Geometry.degreesToRadians (-15.0 * (i + 1));
- ties[i].rotate (vector, theta);
- pt.x = Math.sin (-theta) * arc.radius;
- pt.y = - Math.cos (theta) * arc.radius;
- ties[i].translate (pt);
- }
-
- }
-
- void setConnectionPoints () {
- connectionPoints[0].x = arc.v1.x;
- connectionPoints[0].y = arc.v1.y;
- connectionPoints[1].x = arc.v2.x;
- connectionPoints[1].y = arc.v2.y;
- cx = arc.arcTo.x;
- cy = arc.arcTo.y;
- }
-
- void restore() {
-
- x = ox;
- y = oy;
- super.restore();
- setMainLines();
- setTies();
- setConnectionPoints();
- rotate(Geometry.FORTY_FIVE_DEGREES);
- }
-
- void move(int argX, int argY) {
-
- DblPoint vector = arc.moveTo (
- (double) argX, (double) argY);
-
- for (int i = 0; i < tieCnt; i++)
- ties[i].translate(vector);
-
- setConnectionPoints();
-
- }
-
- void rotate(double theta) {
-
- DblPoint vector;
-
- if (transformMode == ROTATE_MODE_XY)
- vector = DblPoint.vector (Geometry.ORIGIN, arc.v1);
- else if (transformMode == ROTATE_MODE_PQ)
- vector = DblPoint.vector (Geometry.ORIGIN, arc.v2);
- else
- vector = DblPoint.vector (Geometry.ORIGIN, arc.arcTo);
-
- arc.rotate(vector, theta);
- for (int i = 0; i < tieCnt; i++)
- ties[i].rotate(vector, theta);
-
- setConnectionPoints();
- }
-
- void draw (Graphics g) {
-
- if (transformMode == NOT_GRIPPED)
- g.setColor(Color.black);
- else
- g.setColor(Color.blue);
-
- arc.draw (g);
-
- super.draw(g);
- }
- }
-